package edu.njust.httpmanager.core;

import com.alibaba.fastjson2.JSON;
import edu.njust.httpmanager.common.Result;
import edu.njust.httpmanager.entity.Api;
import edu.njust.httpmanager.exception.ApiException;
import edu.njust.httpmanager.utils.ValidatorUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Map;

@Slf4j
@Component
public class RequestHandler {

    @Resource
    private OkHttpClient httpClient;

    public Result<?> sendRequest(Api api) {

        String method = api.getMethod();
        String url = api.getUrl();
        String requestHeaders = api.getRequestHeaders();
        String requestBody = api.getRequestBody();


        HttpUrl httpUrl = HttpUrl.parse(url);
        ValidatorUtil.requireNonnull(httpUrl, "请求路径不合法");

        Request request = new Request.Builder().url(httpUrl)
                .method(method, handleBody(requestBody, "application/json"))
                .build();

        if (requestHeaders != null) {
            request = request.newBuilder().headers(handleHeaders(requestHeaders)).build();
        }

        try (Response response = httpClient.newCall(request).execute()) {

            ResponseBody body = response.body();
            assert body != null;

            return Result.success(body.string());

        } catch (IOException e) {
            log.warn("API - {}, 远程调用失败：{}", api.getId(), e.getMessage());
            throw new ApiException(e.getMessage());
        }

    }

    @SuppressWarnings("unchecked")
    private Headers handleHeaders(String headers) {

        Map<String, String> headerMap = (Map<String, String>) JSON.parseObject(headers, Map.class);
        return Headers.of(headerMap);

    }

    private RequestBody handleBody(String body, String type) {
        if (StringUtils.isAnyBlank(body)) {
            return null;
        }

        return RequestBody.create(body, MediaType.parse(type));
    }
}
